package com.boilermaker.mq.mqserver.manager;

import com.boilermaker.mq.common.MqException;
import com.boilermaker.mq.mqserver.core.Binding;
import com.boilermaker.mq.mqserver.core.Exchange;
import com.boilermaker.mq.mqserver.core.MSGQueue;
import com.boilermaker.mq.mqserver.core.Message;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/*
 * 这个类将进一步封装 DataBaseManager 和 MessageFileManager 的操作
 * 作为一个统一的操作硬盘的接口暴露给上层代码（上层代码不关心数据来自数据库还是文件）
 */
@Slf4j
public class DiskDataCenter {
    private DataBaseManager dataBaseManager = new DataBaseManager();
    private MessageFileManager messageFileManager = new MessageFileManager();

    // 初始化
    public void init() {
        dataBaseManager.init();
    }

    /*
     * 封装交换机操作
     */

    public void insertExchange(Exchange exchange) {
        dataBaseManager.insertExchange(exchange);
    }

    public void deleteExchange(String name) {
        dataBaseManager.deleteExchange(name);
    }

    public List<Exchange> selectAllExchanges() {
        return dataBaseManager.selectAllExchanges();
    }

    /*
     * 封装队列操作
     */

    public void insertQueue(MSGQueue queue) throws IOException {
        dataBaseManager.insertQueue(queue);
        // 新增一个队列，不仅仅意味着在数据库中注册队列的信息，也意味着该队列已经具有接收保存消息的能力（需要创建队列对应的消息文件）
        messageFileManager.createQueueFile(queue.getName());
    }

    public void deleteQueue(String name) throws IOException {
        dataBaseManager.deleteQueue(name);
        // 删除一个队列，不仅仅需要在数据库中清除队列的信息，也需要删除队列对应的消息文件
        messageFileManager.deleteQueueFile(name);
    }

    public List<MSGQueue> selectAllQueue() {
        return dataBaseManager.selectAllQueue();
    }

    /*
     * 封装绑定操作
     */

    public void insertBinding(Binding binding) {
        dataBaseManager.insertBinding(binding);
    }

    public void deleteBinding(Binding binding) {
        dataBaseManager.deleteBinding(binding);
    }

    public List<Binding> selectAllBinding() {
        return dataBaseManager.selectAllBinding();
    }

    /*
     * 封装消息操作
     */

    public void sendMessage(MSGQueue queue, Message message) throws MqException, IOException {
        messageFileManager.sendMessage(queue, message);
    }

    public void deleteMessage(MSGQueue queue, Message message) throws IOException, ClassNotFoundException, MqException {
        messageFileManager.deleteMessage(queue, message);
        // 检查是否需要垃圾回收，对 GC 实现自动化
        if (messageFileManager.checkGC(queue.getName())) {
            messageFileManager.gc(queue);
        }
    }

    public LinkedList<Message> loadAllMessageFromQueue(String queueName) throws IOException, ClassNotFoundException, MqException {
        return messageFileManager.loadAllMessageFromQueue(queueName);
    }
}
